
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import javax.swing.JButton;
import javax.swing.JPanel;

public class ViewPanelMapSelector extends AbstractView {
	
	private PanelMapSelector panelMapSelector;
	private ControllerMenu controller;
	private Integer selectedMapIndex;
	
	/*
	 * Custom cursors
	 */
	private Cursor cursorLeft;
	private Cursor cursorRight;
	
	public class PanelMapSelector extends JPanel implements MouseMotionListener, MouseListener {
		
		private static final long serialVersionUID = 1L;
		
		/*
		 * Inner class constructor
		 */
		public PanelMapSelector() {
			setLayout(null);
			addComponents();
			
			/*
			 * Add mouse motion listener and mouse listener
			 */
			addMouseMotionListener(this);
			addMouseListener(this);
		}
		
		public void paintComponent(Graphics g) {
			Graphics2D g2D = (Graphics2D) g;
			
			/*
	         * Draw background image
	         */
			double imageWidth = WorldWar.imageLoader.getImageByName(ImageStructure.IMAGE_NAME_PANEL_MENU_BACKGROUND).getWidth();
	        double imageHeight = WorldWar.imageLoader.getImageByName(ImageStructure.IMAGE_NAME_PANEL_MENU_BACKGROUND).getHeight();

	        double sx = (ViewFrameMain.PANEL_PIXEL_WIDTH / imageWidth);
	        double sy = (ViewFrameMain.PANEL_PIXEL_WIDTH / imageHeight);
	        
	        g.clearRect(0, 0, 800, 700);
	        AffineTransform af = AffineTransform.getScaleInstance(sx, sy);
	        g2D.drawImage(WorldWar.imageLoader.getImageByName(ImageStructure.IMAGE_NAME_PANEL_MENU_BACKGROUND), af, this);
	        
	        /*
        	 * Map selector area
        	 */
	        g2D.setColor(new Color(0.1f, 0.1f, 0.1f, 0.3f));
	        g2D.fillRect(0, 100, 800, 400);
	        
	        /*
	         * Draw selected map image and title
	         */
	        BufferedImage mapImage = WorldWar.imageLoader.getImageByName(
        			getMapImageNameByMapName(WorldWar.mapLoader.getMapsList().get(selectedMapIndex).getMapName()));
	        g2D.drawImage(mapImage, (ViewFrameMain.PANEL_PIXEL_WIDTH - 200) / 2, 140, 200, 280, this);
	        g2D.setColor(Color.DARK_GRAY);
	        g2D.setFont(new Font("Arial", Font.PLAIN, 20));
	        g2D.drawString(WorldWar.mapLoader.getMapsList().get(selectedMapIndex).getMapTitle(), 355, 450);
	        
	        /*
	         * Draw nearby candidate maps if they exist
	         */
	        if(selectedMapIndex < WorldWar.mapLoader.getMapsList().size() - 1) {
	        	mapImage = WorldWar.imageLoader.getImageByName(
	        			getMapImageNameByMapName(WorldWar.mapLoader.getMapsList().get(selectedMapIndex + 1).getMapName()));
	        	g2D.drawImage(mapImage, (ViewFrameMain.PANEL_PIXEL_WIDTH - 200) / 2 + 270, 160, 200 * 3/4, 280 * 3/4, this);
	        }
	        if(selectedMapIndex > 0) {
	        	mapImage = WorldWar.imageLoader.getImageByName(
	        			getMapImageNameByMapName(WorldWar.mapLoader.getMapsList().get(selectedMapIndex - 1).getMapName()));
	        	g2D.drawImage(mapImage, (ViewFrameMain.PANEL_PIXEL_WIDTH - 200) / 2 - 220, 160, 200 * 3/4, 280 * 3/4, this);   
	        }
		}
		
		/*
		 * Get map image name by map name
		 */
		private String getMapImageNameByMapName(String mN) {
			if(mN.equals(Map.MAP_NAME_0))
				return ImageStructure.IMAGE_NAME_MAPIMAGE_1;
			else if(mN.equals(Map.MAP_NAME_1))
				return ImageStructure.IMAGE_NAME_MAPIMAGE_2;
			else if(mN.equals(Map.MAP_NAME_2))
				return ImageStructure.IMAGE_NAME_MAPIMAGE_3;
			else if(mN.equals(Map.MAP_NAME_3))
				return ImageStructure.IMAGE_NAME_MAPIMAGE_4;
			return null;
		}
		
		/*
		 * Add buttons to panelMapSelector
		 */
		private void addComponents() {
	    	/*
			 * Clear the panel
			 */
			this.removeAll();
			
			/*
	         * Initialize the buttons
	         */
			JButton buttonReturnToMenu = new JButton("Return To Menu");
			JButton buttonGameStart = new JButton("Game Start");
			
			buttonReturnToMenu.setBounds(50, 580, 150, 50);
			buttonGameStart.setBounds(ViewFrameMain.PANEL_PIXEL_WIDTH - 150 - 50, 580, 150, 50);
			
			/*
	         * Add ActionListener to buttons
	         */
			buttonReturnToMenu.addActionListener(new ActionListener() {
	            public void actionPerformed(ActionEvent evt) {
	            	System.out.println();
	            	controller.buttonPressedReturnToMenu();
	            }
	        });
			buttonGameStart.addActionListener(new ActionListener() {
	            public void actionPerformed(ActionEvent evt) {
	            	System.out.println();
	            	controller.buttonPressedGameStart();
	            }
	        });
			
			/*
	         * Add buttons to the panel
	         */
			this.add(buttonReturnToMenu);
			this.add(buttonGameStart);
			
			/*
			 * Refresh
			 */
			this.repaint();
	    }

		@Override
		public void mouseClicked(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mousePressed(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseReleased(MouseEvent evt) {
			// TODO Auto-generated method stub
			
			if(evt.getY() >= 500 || evt.getY() <= 100) {
				this.setCursor(Cursor.getDefaultCursor());
				return;
			}
			
			if(evt.getX() <= (ViewFrameMain.PANEL_PIXEL_WIDTH - 200) / 2 - 20) {
				System.out.println();
				controller.selectMapShiftLeft(selectedMapIndex);
			}
			else if(evt.getX() >= (ViewFrameMain.PANEL_PIXEL_WIDTH - 200) / 2 + 200 + 20) {
				System.out.println();
				controller.selectMapShiftRight(selectedMapIndex);
			}
			else {
				return;
			}
		}

		@Override
		public void mouseDragged(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseMoved(MouseEvent evt) {
			// TODO Auto-generated method stub
			
			if(evt.getY() >= 500 || evt.getY() <= 100) {
				setCursor(Cursor.getDefaultCursor());
				return;
			}
			
			if(evt.getX() <= (ViewFrameMain.PANEL_PIXEL_WIDTH - 200) / 2 - 20) {
				setCursor(cursorLeft);
			}
			else if(evt.getX() >= (ViewFrameMain.PANEL_PIXEL_WIDTH - 200) / 2 + 200 + 20) {
				setCursor(cursorRight);
			}
			else {
				setCursor(Cursor.getDefaultCursor());
			}
		}
	}
	
	/*
	 * Constructor
	 */
	public ViewPanelMapSelector() {
		selectedMapIndex = 0;
		createCursors();
		panelMapSelector = new PanelMapSelector();
	}
	
	/*
	 * Create custom cursors
	 */
	private void createCursors() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		Point cursorHotSpot = new Point(0,16);
		cursorLeft = toolkit.createCustomCursor(WorldWar.imageLoader.getImageByName(ImageStructure.IMAGE_NAME_CURSOR_LEFT), cursorHotSpot, "Cursor");
		cursorRight = toolkit.createCustomCursor(WorldWar.imageLoader.getImageByName(ImageStructure.IMAGE_NAME_CURSOR_RIGHT), cursorHotSpot, "Cursor");
	}
	
	/*
	 * Accessors
	 */
	public JPanel getPanel() {
		return panelMapSelector;
	}
	
	public ControllerMenu getController() {
		return controller;
	}
	
	/*
	 * Mutators
	 */
	public void setController(ControllerMenu ctrl) {
		controller = ctrl;
	}
	
	/*
	 * Event handler for modelPropertyChange events coming from the controller
	 */
	public void modelPropertyChange(final PropertyChangeEvent evt) {
		System.out.println(this.getClass().toString() + ".modelPropertyChange() called -- " + 
				evt.getPropertyName() + ": " + evt.getOldValue().toString() + 
				" -> " + evt.getNewValue().toString());
		
		if(evt.getPropertyName().equals("selectedMapIndex")) {
			selectedMapIndex = (Integer) evt.getNewValue();
			panelMapSelector.repaint();
		}
	}
}
